package com.example.dataservice.serviceimpl;

import com.example.common.constants.YLBConstant;
import com.example.dataservice.mapper.BidInfoMapper;
import com.example.dataservice.mapper.FinanceAccountMapper;
import com.example.dataservice.mapper.IncomeRecordMapper;
import com.example.dataservice.mapper.ProductInfoMapper;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.example.api.model.BidInfo;
import org.example.api.model.FinanceAccount;
import org.example.api.model.IncomeRecord;
import org.example.api.model.ProductInfo;
import org.example.api.service.IncomeService;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Year;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @description: TODO
 * @author: uu
 * @data: 2023/7/22 下午 12:19
 * @version: v1.0
 */
@DubboService(interfaceClass = IncomeService.class, version = "1.0")
public class IncomeServiceImpl implements IncomeService {
    @Resource
    private ProductInfoMapper productInfoMapper;
    @Resource
    private BidInfoMapper bidInfoMapper;
    @Resource
    private IncomeRecordMapper incomeRecordMapper;
    @Resource
    private FinanceAccountMapper accountMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    /*收益计划*/
    public synchronized void generateIncomePlan() {
        Date cur = new Date();
        int day = Year.of(LocalDate.now().getYear()).length();

        Date begin = DateUtils.truncate(DateUtils.addDays(cur,-1), Calendar.DATE);
        Date end = DateUtils.truncate(cur, Calendar.DATE);
        // 1. 获取满标的理财产品
        List<ProductInfo> productInfos = productInfoMapper.selectStatusProduct(YLBConstant.PRODUCT_STATUS_SELLED, begin, end);

        // 2. 查询满标产品的投资记录
        productInfos.forEach(productInfo -> {

            List<BidInfo> bidInfos = bidInfoMapper.selectByProductId(productInfo.getId());
            BigDecimal rate = productInfo.getRate();
            // 日利率
            BigDecimal dayRate = rate.divide(new BigDecimal(day).multiply(new BigDecimal(100)), 10, RoundingMode.HALF_UP);
            // 周期
            Integer cycle;
            // 新手包周期是日
            if (productInfo.getProductType() == YLBConstant.PRODUCT_TYPE_XINSHOUBAO){
                cycle = productInfo.getCycle();
            }else {
                cycle = productInfo.getCycle() * 30;
            }
            // 到期时间
            Date incomeDate = DateUtils.addDays(productInfo.getProductFullTime(), 1+cycle);
            // 3. 计算利息
            bidInfos.forEach(bidInfo -> {
                // 利息 = 本金*周期*利率
                BigDecimal income = bidInfo.getBidMoney().multiply(new BigDecimal(cycle)).multiply(dayRate);

                // 4. 创建收益记录
                IncomeRecord record = new IncomeRecord();
                record.setUid(bidInfo.getUid());
                record.setProdId(bidInfo.getProdId());
                record.setBidId(bidInfo.getId());
                record.setBidMoney(bidInfo.getBidMoney());
                record.setIncomeDate(incomeDate);
                record.setIncomeMoney(income);
                record.setIncomeStatus(YLBConstant.INCOME_STATUS_PLAN);
                int count = incomeRecordMapper.insertSelective(record);
                if (count < 1){
                    throw new RuntimeException("创建收益失败");
                }
            });
            // 5. 更新产品的状态
            ProductInfo updateProductInfo = new ProductInfo();
            updateProductInfo.setId(productInfo.getId());
            updateProductInfo.setProductStatus(YLBConstant.PRODUCT_STATUS_PLAN);
            int count = productInfoMapper.updateByPrimaryKeySelective(updateProductInfo);
            if (count < 1){
                throw new RuntimeException("产品状态更新失败");
            }
        });
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    /*收益返还*/
    public synchronized void generateIncomeBack() {
        Date cur = new Date();
        Date pre = DateUtils.truncate(DateUtils.addDays(cur, -1), Calendar.DATE);
        // 1. 获取到期要返还的收益记录
        List<IncomeRecord> incomeRecords = incomeRecordMapper.selectExpiredIncome(pre);
        // 2. 收益返还，本金+利息
        incomeRecords.forEach(incomeRecord -> {
            FinanceAccount account = new FinanceAccount();
            account.setUid(incomeRecord.getUid());
            BigDecimal bidMoney = incomeRecord.getBidMoney();
            BigDecimal incomeMoney = incomeRecord.getIncomeMoney();
            BigDecimal total = bidMoney.add(incomeMoney);
            // 总收益
            account.setAvailableMoney(total);

            // 更新资金
            int count = accountMapper.updateAvailableByIncomeBack(account);
            if (count < 1){
                throw new RuntimeException("专户资金更新失败");
            }

            // 3. 更新收益记录为 (1) 返还
            incomeRecord.setIncomeStatus(YLBConstant.INCOME_STATUS_BACK);
            count = incomeRecordMapper.updateByPrimaryKeySelective(incomeRecord);
            if (count < 1){
                throw new RuntimeException("收益状态更新失败");
            }
        });


    }

}
